package com.mingda.weathermagiccenter.task;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mingda.weathermagiccenter.dto.BizBean;
import com.mingda.weathermagiccenter.dto.HaiKangStationDetailDTO;
import com.mingda.weathermagiccenter.dto.StationBean;
import com.mingda.weathermagiccenter.dto.WeatherResultBean;
import com.mingda.weathermagiccenter.pojo.WsStation;
import com.mingda.weathermagiccenter.pojo.WsStationData;
import com.mingda.weathermagiccenter.pojo.WsStationDataCur;
import com.mingda.weathermagiccenter.service.WsStationDataCurService;
import com.mingda.weathermagiccenter.service.WsStationDataService;
import com.mingda.weathermagiccenter.service.WsStationService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Async
@Slf4j
@Configuration // 1.主要用于标记配置类，兼备Component的效果。
@EnableScheduling // 2.开启定时任务
@ConditionalOnProperty(prefix = "dxalhikapi",name = "enabled",havingValue = "true")
public class InsertDxalHikTask {


    @Autowired
    private WsStationDataService wsStationDataService;
    @Autowired
    private WsStationDataCurService wsStationDataCurService;
    @Autowired
    private WsStationService wsStationService;

    @Autowired
    private RestTemplate restTemplateWithToken;

    @Value("${dxalhikapi.hikdetailurl:}")
    private String hikurl;

    /**
     * 从远端API接口获得站点天气数据进行同步从头开始同步
     * 简单点 实时获取已小时为单位s
     */

    @Scheduled(cron = "${dxalhikapi.cron}")
    public void asyncdxalhik() {
        log.info("开始同步海康火险因子监测站数据");
        LambdaQueryWrapper<WsStation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WsStation::getStationtype,"3");
        List<WsStation>  list =  wsStationService.list(queryWrapper);

        for(WsStation wsStation : list) {
            // 获取当前时间
            LocalDateTime now = LocalDateTime.now();
            // 将时间四舍五入到整点
            LocalDateTime roundedTime = now.withMinute(0).withSecond(0).withNano(0);
            // 格式化时间字符串
            DateTimeFormatter formatterstart = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:00:00");
            DateTimeFormatter formatterend = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:59:59");
            DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH");
            String start = roundedTime.format(formatterstart);
            String end = roundedTime.format(formatterend);
            Map<String, String> param = new HashMap<String, String>();
            param.put("startTime", start);
            param.put("endTime", end);
            param.put("id", wsStation.getStationkey()); //站点ID
            String requesturl = hikurl + "?mode=2&startTime={startTime}&endTime={endTime}&id={id}";

            List<WsStationData>  datalist = new ArrayList<WsStationData>();
            List<HaiKangStationDetailDTO> stations = new ArrayList<HaiKangStationDetailDTO>();
            ResponseEntity<String> res = restTemplateWithToken.getForEntity(requesturl, String.class, param);
            String bodystr = res.getBody();
            JSONObject rowData = JSONObject.parseObject(bodystr);
            if (rowData != null) {
                JSONArray array = rowData.getJSONArray("data");
                stations = array.toJavaList(HaiKangStationDetailDTO.class);
                outer:
                for (HaiKangStationDetailDTO point : stations) {
                    WsStationData ws = new WsStationData();
                    ws.setStationkey(point.getDeviceIndexcode());
                    LocalDateTime dateTime = LocalDateTime.parse(point.getTimeStr(), inputFormatter);
                    ws.setTimebase(dateTime);

                    switch (point.getDataType()){
                        case 10000100:
                            ws.setTemp(point.getDataValue());
                            break;
                        case 10000200:
                            ws.setHumi(point.getDataValue());
                            break;
                        case 10000300:
                            ws.setPres(point.getDataValue());
                            break;
                        case 10000400:
                            ws.setWin10Dir((int)point.getDataValue());
                            break;
                        case 10000500:
                            ws.setWin10Vel(point.getDataValue());
                            break;
                        case 10000600:
                            ws.setPrec(point.getDataValue());
                            break;
                        case 30000300:
                            ws.setWaterrate(point.getDataValue());
                            break;
                        case 20000300:
                            ws.setWaterrateOutPlant(point.getDataValue());
                            break;
                        case 20000400:
                            ws.setWaterrateInsidePlant(point.getDataValue());
                            break;
                        default:
                            continue outer;
                    }

                    String month = point.getTimeStr().replace("-","");
                    month = month.substring(0,6);
                    ws.setMonth(month);   //表分区月份 比填写*
                    datalist.add(ws);
                }

                log.info("更新同步海康火险因子监测站{}条"+ datalist.size());
                List<WsStationData> wsStationDatas = mergeWsStationData(datalist);
                List<WsStationDataCur> list2 = new ArrayList<WsStationDataCur>();
                for(WsStationData ws: wsStationDatas) {
                    WsStationDataCur wsc = new WsStationDataCur();
                    try {
                        BeanUtils.copyProperties(wsc, ws);
                        list2.add(wsc);
                    } catch (Exception e) {

                    }
                }



                wsStationDataService.saveOrUpdateBatchById(wsStationDatas);
                wsStationDataCurService.saveOrUpdateBatchById(list2); //插入当前表


            }
        }
    }


    public static List<WsStationData> mergeWsStationData(List<WsStationData> data) {
        Map<String, WsStationData> mergedData = data.stream()
                .collect(Collectors.toMap(
                        d -> d.getStationkey() + "_" + d.getTimebase(),
                        Function.identity(),
                        (existing, newData) -> mergeWsStationData(existing, newData)
                ));

        return mergedData.values().stream()
                .collect(Collectors.toList());
    }



    private static WsStationData mergeWsStationData(WsStationData existing, WsStationData newData) {
        WsStationData merged = new WsStationData();
        merged.setStationkey(existing.getStationkey());
        merged.setTimebase(existing.getTimebase());
        merged.setMonth(existing.getMonth());
        // Merge the data fields
        merged.setTemp(existing.getTemp() != null ? existing.getTemp() : newData.getTemp());
        merged.setHumi(existing.getHumi() != null ? existing.getHumi() : newData.getHumi());
        merged.setPres(existing.getPres() != null ? existing.getPres() : newData.getPres());
        merged.setWin10Dir(existing.getWin10Dir() != null ? existing.getWin10Dir() : newData.getWin10Dir());
        merged.setWin10Vel(existing.getWin10Vel() != null ? existing.getWin10Vel() : newData.getWin10Vel());
        merged.setPrec(existing.getPrec() != null ? existing.getPrec() : newData.getPrec());
        merged.setWaterrate(existing.getWaterrate() != null ? existing.getWaterrate() : newData.getWaterrate());
        merged.setWaterrateOutPlant(existing.getWaterrateOutPlant() != null ? existing.getWaterrateOutPlant() : newData.getWaterrateOutPlant());
        merged.setWaterrateInsidePlant(existing.getWaterrateInsidePlant() != null ? existing.getWaterrateInsidePlant() : newData.getWaterrateInsidePlant());

        return merged;
    }


}
